iT邦幫忙

第 11 屆 iThome 鐵人賽

DAY 13
1

終於來到Angular Taiwan線上讀書會,第6季最後一集了
想起來當時我也不是每集看直播
事後看youtub影片,也是看20~30分鐘就睡著
(個人有學習容易睡著的現象)

先打一下預防針:
由於第3季的講者大都有準備文件(有的我有附網址、有的我找不到)
為了避免抄襲,還是請大家去看講者提供的文章
所以第3季的心得會爛爛的
(目前第3季快寫完了,比起第6季有點爛尾現象)

重點是如果有看到我寫超精采的,一定值得初學者去多看幾次影片!!

小弟在最後一天(9/17)開賽後,庫存只有10篇文章左右
(目前庫存只有5篇左右)
最近為了趕文章,所以文章品質低下,希望後面如果趕到安全時,可以回來

  • 調格式
  • 加註解
  • 加一些在其他地方學到的資源的補充
    (例如:怎麼替換測試用service,怎麼用非同步…等)

建議參考文件

畢竟一集30~70分鐘左右,講者只是分享重點,說明這是值得學的好東西
再來還是要自己去看官網文件、其他人寫的文件、或開源的專案

接下來明天就會看第3季的各種測試啦
以前也是超想學,但又是各種睡著,一直學不起來
利用鐵人賽強迫自己看過一輪

最後再來看第5季RxJS

跟第6季不同的事,
第3季、第5季有一些如果比較難打成筆記的,可能會2~3集合併成一篇
一些要付費或我完全試不出來的,也可能會跳過

最後一集Testing由Leo老師擔任終結者
影片網址:
https://www.youtube.com/watch?v=peaaGkcoTtY&list=PL9LUW6O9WZqgUMHwDsKQf3prtqVvjGZ6S&index=1

投影片教學

為什麼要寫測試

  1. 程式發生錯誤,怎麼模擬出當時狀況及進行Debug?
  2. 修改function後,會不會導致別的程式掛掉?
  3. 哪些測過,哪些還沒測過?(所以要有系統的測)

目的

  1. 很快的知道測試結果
  2. 提高程式碼品質
  3. 節省Debgu時間
  4. 縮短專案時程(熟練後)

種類(只列基本重要的3項)

  1. 單元測試
  • 用來模擬外部如何使用測試目標物件,驗證其行為是否符合預期
  • 從最小範圍開始測
  • 單元是指一個class或一個module

來看一下ng new出來就有的app.component.spec.ts

import { TestBed, async } from '@angular/core/testing';
import { RouterTestingModule } from '@angular/router/testing';
import { AppComponent } from './app.component';

describe('AppComponent', () => {
  beforeEach(async(() => {
  ^^^^^^^^^ 在每一個it之前,都會先跑一次。跑完再跑it
    TestBed.configureTestingModule({
      imports: [
        RouterTestingModule
      ],
      declarations: [
        AppComponent
      ],
    }).compileComponents();
  }));
  
  // afterEach,在每一個it之後都執行1次
  // 抽出每個it重複的部分
  // beforeAll,在所有的it之前,執行1次
  // afterAll,在所有的it之後,執行1次
  
  // xdiscribe,乎略整個describe
  // xit ,乎略這個it
  
  // discribe跟it都可以巢狀
  // beforEach的影響範圍就是跟discribe同一層
  
  it('should create the app', () => {
      ^^^^^^^^^^^^^ 說明這個測試案例要幹麻的
    const fixture = TestBed.createComponent(AppComponent);
    const app = fixture.debugElement.componentInstance;
    // 有無成功拿到class的實體
    expect(app).toBeTruthy();
  });

  it(`should have as title 'day03'`, () => {
    const fixture = TestBed.createComponent(AppComponent);
    const app = fixture.debugElement.componentInstance;
    // app.title是否等於'day03'
    expect(app.title).toEqual('day03');
  });

  it('should render title in a h1 tag', () => {
    const fixture = TestBed.createComponent(AppComponent);
    fixture.detectChanges();
    const compiled = fixture.debugElement.nativeElement;
    // h1的內容是否包含'Welcome to day03!'
    expect(compiled.querySelector('h1').textContent).toContain('Welcome to day03!');
  });
});

ng test 或 npm run test(定義在package.json)

來自己寫個簡單的測試,測function

app.component.spec.ts

// 1、先從使用的角度寫測試案例
// class有哪些功能?怎麼使用這些功能?
// 有一個hi的function,當傳入xxx時,會回傳Hi, xxx
it('預期看到 Hi, Leo',() => {
^^ 測試案例
    const fixture = TestBed.createComponent(AppComponent);
    const app = fixture.debugElement.componentInstance;
    except(app.hi('Leo')).toEqual('Hi, Leo');
                                   ^^^^^^^ 若相等就綠燈

app.component.ts

// 2、寫好測試案例,再來寫hi()
hi(name: string): string{
    return `Hi, ${name}`;
            ^^^^^^^^^^^
}
  1. 整合測試
  • 兩個以上的類別做整合,並測試運作關係是不是正確的
  1. 驗收測試(接近e2e測試,模擬使用者操作系統,測試有無符合各項需求)
  • 系統行為與功能面的規範
  • 用來說明某一個user story
  • 使用者的角度來檢示是否符合使用者需求

心法

  • 先寫測試案例,再寫程式。再努力通過測試
  • 寫程式是為了通過測試
  • 以調用方的角度來call該function,並從調用方的角度來定出期望的結果
  • (紅燈 -> 綠燈 -> 重構 -> 紅燈 -> … )
  • 絕不跳過重構(一直改進)
  • 寫完測試,儘快讓紅燈變綠燈
  • 若一直無法變紅燈,放慢腳步,是否測試案例要再拆解成更細的

覆蓋率(健康指標)

  • 不用要求100%
  • 重要的scenario有無含蓋多一點情境?
  • 有哪些還沒被測過?
  • 發生測試失敗時,失敗的原因點是否有被測試案例含蓋到?

TDD vs ATTD

TDD 測試驅動開發(Test-Driven Development)
ATTD 驗收測試驅動開發(Acceptance Test Driven Developent)

  • 使用TDD最常見的問題:
  1. 用戶想要的功能沒有開發
  2. 開發的功能不是用戶想要的
  3. 用戶和開發人員溝通語言不同(一個講流程需求,一個講技術)
TDD
單元測試 -> 整合測試 -> 驗收測試
        <-        <-         ATTD

ATTD實務上的困難點

  • 開發前需求還沒定下來
  • 客戶無法於開發前提供驗收測試案例(Test Case)
  • 可能需求明確的系統再造,或開發自己的產品(如:需求與寫程式的同一人)。較好實現美好的ATTD

======== 其他Q&A 或 特性 ========

discribe跟it都可以巢狀

beforEach的影響範圍就是跟discribe同一層

const count = 0;
describe('第1層的describe', () => {
    beforEach(() => { count+=1; });
    it('1-1',()=>{...});
    
    describe('第2層的describe', () => {
        // 1-1、1-2不會觸發第2層的describe 的 beforEach
        beforEach(() => { count+=1; }); 
        it('2-1',()=>{...});
    }
    
    it('1-2',()=>{...});
}

Table的資料怎麼測試?

  1. 要確認model與form有無綁定成功
  2. 測試時,資料要排除外在變因,通常要用測試用的假資料
    常見字如:MOCK、fake。
    或利用interface或DI(相依注入)的方式,將真實的Service抽換成測試用Service
    或利用spyOn抽換掉component裡的function
  • 模擬API回傳回來的資料
    mock-data.ts
export const mockData = {
    success: false,
    errorCode: 0, // 所有的errorCode測一試
    response: {
        data: 'Leo' // 餵各種前端吃的data是否仍能正常,如:極端值
    }
}

app.component.ts

假設有一個取資料的function
getData(): any {
    return {
        success: false,
        errorCode: 9999, 
        response: {
            data: null 
        }
    }
}
  • 利用spyOn抽換掉component裡的function
    寫在spec裡
    app.component.spec.ts
取代app實例裡的getData(),並改為回傳mockData
const data = spyOn(app, 'getData').and.returnValue(mockData);

上一篇
Day12_Pipe
下一篇
Day14_RxJs&Promise(AngularTaiwan線上讀書會第3季-主題:測試)
系列文
Angular新手村學習筆記(2019)33
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

1 則留言

0

我要留言

立即登入留言